<template>
  <div class="login-container">
    <el-form
      class="login-form"
      auto-complete="on"
      label-position="left"
      :model="formData"
      :rules="formDataRules"
      ref="formRef"
    >
      <div class="title-container">
        <h3 class="title">尚品汇后台管理</h3>
      </div>

      <el-form-item prop="username">
        <span class="svg-container">
          <svg-icon name="ele-UserFilled" />
        </span>
        <el-input
          placeholder="Username"
          name="username"
          type="text"
          tabindex="1"
          auto-complete="on"
          v-model="formData.username"
        />
      </el-form-item>

      <el-form-item prop="password">
        <span class="svg-container">
          <svg-icon name="ele-Lock" />
        </span>
        <el-input
          placeholder="Password"
          name="password"
          :type="showPwd ? 'text' : 'password'"
          tabindex="2"
          auto-complete="on"
          v-model="formData.password"
          @keydown.enter="loginHandler"
        />
        <span class="show-pwd" @click="toggleShowPassword">
          <svg-icon :name="showPwd ? 'ele-Hide' : 'ele-View'" />
        </span>
      </el-form-item>

      <el-button
        type="primary"
        style="width: 100%; margin-bottom: 30px; height: 40px"
        @click="loginHandler"
        :icon="loadingShow ? 'ele-Loading' : ''"
      >
        登 陆</el-button
      >
    </el-form>
  </div>
</template>

<script lang="ts">
export default {
  name: "Login",
};
</script>

<script lang="ts" setup>
/**
 * 做数据（表单）校验核心几个要素：
 *
 * - 要校验的数据
 * - 校验规则
 * - 结果提示
 *   - 单个数据的校验结果：针对某个输入的数据进行独立的提示
 *   - 全部数据的校验结果：提交表单的时候针对整个数据的校验结果进行判断
 *
 * 使用 ElementPlus 的 Form 做数据的校验呢？
 * - model: 表单数据对象，要校验的数据
 * - rules: 表单验证规则
 * - 在 el-form-item 的 prop 属性中指定绑定的字段
 *
 * 当我们需要获取整个表单中绑定的数据的验证状态，我们需要
 * - 通过 ref 获取到表单实例对象
 * - 通过表单实例对象提供的方法
 */
import { useUserStore } from "@/stores/user";
import { reactive, ref } from "vue";
import { useRouter, useRoute } from "vue-router";
import type { FormRules } from "element-plus";
import { ElMessage } from "element-plus";

const userStore = useUserStore();
const router = useRouter();
const route = useRoute();
const loadingShow = ref(false);
// 绑定表单，收集用户输入的数据
const formData = reactive({
  username: "",
  password: "",
});
//初始化showPwd初始值为false
const showPwd = ref(false);

function toggleShowPassword() {
  //获取变量值,并将其转为boolean类型
  const isShow = Boolean(showPwd.value);
  showPwd.value = !isShow;
}

//表单校验规则
//是一个对象类型
//key:fromData 中要校验的数据的名称
//值也是一个对象：这个对象就是校验器（校验配置）
//校验配置：https://github.com/yiminghe/async-validator

/**
 *
 * export interface RuleItem {
 *     // 数据的类型
 *     type?: RuleType;
 *     // 是否必填
 *     required?: boolean;
 *     // 验证的正则，但一些数据验证的规则比较复杂的时候，可以使用正则
 *     pattern?: RegExp | string;
 *     // 最小值
 *     min?: number;
 *     // 最大值
 *     max?: number;
 *     // 字符串最大长度
 *     len?: number;
 *     // 枚举，enum: [5,10,15];
 *     enum?: Array<string | number | boolean | null | undefined>;
 *     // 是否允许包含空格
 *     whitespace?: boolean;
 *     // 当前字段的验证是根据其它指定 fields 的颜色结果来决定
 *     fields?: Record<string, Rule>;
 *     // 验证选项，配置验证的一些行为
 *     options?: ValidateOption;
 *     defaultField?: Rule;
 *     transform?: (value: Value) => Value;
 *     // 验证提示消息
 *     message?: string | ((a?: string) => string);
 *     // 下面两个是自定义的验证器，所有上面的配置都无法满足我们当前的验证需求的时候，就可以自定义验证的规则
 *     // validator，asyncValidator
 *     // validator 场景，当前用户名是否为空，或者多少个字符
 *     // asyncValidator 一般场景：验证用户名是否已经被注册了
 *     asyncValidator?: (rule: InternalRuleItem, value: Value, callback: (error?: string | Error) => void, source: Values, options: ValidateOption) => void | Promise<void>;
 *     validator?: (rule: InternalRuleItem, value: Value, callback: (error?: string | Error) => void, source: Values, options: ValidateOption) => SyncValidateResult | void;
 *
 *     // 指定触发验证的事件名称
 *     trigger: string;
 * }
 *  */

const formDataRules: FormRules = {
  username: [
    {
      type: "string",
      required: true,
      min: 3,
      max: 10,
      message: "用户名在3-10个字符串之间",
      trigger: "blur",
    },
    {
      asyncValidator() {
        //发送请求,验证用户名是否已经被注册了
        // return Promise.reject("用户名是否已经被注册了");
        return Promise.resolve();
      },
    },
  ],
  password: {
    required: true,
    validator(rule, value, callback) {
      // rule: 当前的验证器对象
      // value: 当前验证的数据的值
      // callback: 类型 next，执行callback告知验证结果
      if (value.length > 3 && value.length < 20) {
        // callback 调用不传递任何参数表示验证成功
        callback();
      } else {
        // 传入Error表示验证失败，Error的message就是验证失败后的提示信息
        callback(new Error("密码长度必须在3-20个字符之间"));
      }
    },
  },
};

//
//表单组件实例对象
const formRef = ref();
/**
 * 指定登录请求
 */
async function loginHandler() {
  try {
    //校验表单的状态
    const result = await formRef.value.validate();
    // console.log(result);
    // 在这里调用这个函数的时候那么这个函数返回的永远是一个成功 切值为undefined的promise 对象
    loadingShow.value = true;
    await userStore.login(formData.username, formData.password);
    // 登录成功了，跳转页面
    const redirectPath: string = route.query.redirect as string;
    router.push(redirectPath ? redirectPath : { name: "HomeIndex" });
  } catch (e) {
    // console.log(123);
    loadingShow.value = false;
    ElMessage.error("验证失败");
  }
}
</script>

<style lang="scss">
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
body {
  margin: 0;
}

$bg: #283443;
$light_gray: #fff;
$cursor: #fff;

@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
  .login-container .el-input input {
    color: $cursor;
  }
}
/* reset element-ui css */
.login-container {
  background-image: url(../../assets/bg.jpg);
  background-color: #2d3a4b;
  background-size: cover;
  .el-input {
    display: inline-block;
    height: 47px;
    width: 85%;
    .el-input__wrapper {
      width: 100%;
      background-color: transparent;
      box-shadow: none;
      input {
        background: transparent;
        border: 0px;
        -webkit-appearance: none;
        border-radius: 0px;
        padding: 12px 5px 12px 15px;
        color: $light_gray;
        height: 47px;
        caret-color: $cursor;

        &:-webkit-autofill {
          box-shadow: 0 0 0px 1000px $bg inset !important;
          -webkit-text-fill-color: $cursor !important;
        }
      }
    }
  }

  .el-form-item {
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(0, 0, 0, 0.1);
    border-radius: 5px;
    color: #454545;
  }
}
</style>

<style lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;

.login-container {
  min-height: 100%;
  width: 100%;
  background-color: $bg;
  overflow: hidden;

  .login-form {
    position: relative;
    width: 520px;
    max-width: 100%;
    padding: 160px 35px 0;
    margin: 0 auto;
    overflow: hidden;
  }

  .tips {
    font-size: 14px;
    color: #fff;
    margin-bottom: 10px;

    span {
      &:first-of-type {
        margin-right: 16px;
      }
    }
  }

  .svg-container {
    padding: 6px 5px 6px 15px;
    color: $dark_gray;
    vertical-align: middle;
    width: 30px;
    display: inline-block;
  }

  .title-container {
    position: relative;

    .title {
      font-size: 26px;
      color: $light_gray;
      margin: 0px auto 40px auto;
      text-align: center;
      font-weight: bold;
    }
  }

  .show-pwd {
    position: absolute;
    right: 10px;
    top: 10px;
    font-size: 16px;
    color: $dark_gray;
    cursor: pointer;
    user-select: none;
  }
}
</style>
